define(
[
    "entity/IndoorMgr", "render/poi/POIRendererMgr", "entity/POI"
],
function(IndoorMgr, POIRendererMgr, POI) {

    return {
        getName: function() {
            return "COMP - INDOOR MGR"
        },

        create: function() {

            var _self = {
                /**
                 * params : [ [], [], [] ]
                 * array of floor => array of { visual: , osmInfo: }
                 */
                init: function(params, ownerPOI, systemMgr) {
                    //Assign members
                    _sourceData     = params;
                    _systemMgr      = systemMgr;
                    _POIRendererMgr = POIRendererMgr.create();
                    _POI            = ownerPOI;
                    _maxFloor       = _curFloor = params.length - 1;

                    //Init indoor POIs
                    _initIndoorPOIs();
                    _self.setVisible(false);

                    //return me
                    return _self;
                },
                
                setVisible: function(val) {
                    _visible = val;
                    _POIRendererMgr.setVisible(val);
                },

                isVisible: function() {
                    return _visible;
                },

                getMaxFloor: function() {
                    return _maxFloor;
                },

                setCurFloor: function(val) {
                    //validate
                    var valid = val >= 0 && val <= _maxFloor;
                    if(!valid)
                        return;
                    
                    //Save value
                    _curFloor = val;

                    //
                    _POIRendererMgr.setDrawUntilMark(_POIs[_curFloor].mark);
                },

                getFloorOf: function(POI) {
                    for(var i = 0; i < _POIs.length; ++i)
                        if(_POIs[i].indexOf(POI) >= 0)
                            return i;

                    return null; 
                },

                getCurFloor: function() {
                    return _curFloor;
                },

                getPOI: function() {
                    return _POI;
                },

                destroy: function() {
                    _destroyIndoorPOIs();
                }
            };


            var _POIRendererMgr;
            var _POIs;
            var _POI;
            var _systemMgr;
            var _visible;
            var _maxFloor;
            var _curFloor;
            var _sourceData;
            var _CLASS = this;

            function _initIndoorPOIs() {
                //Initialize
                _POIRendererMgr.init(_systemMgr);
                _POIs = [];

                //Validate POI whether it is loaded (circular dependency issue)
                POI = require("entity/POI");

                //Build the POIs
                _sourceData.forEach(function(val){
                    //Create this floor array
                    var curFloor = [];
                    _POIs.push(curFloor);

                    //Create POIs for this floor
                    val.forEach(function(val){
                        curFloor.push(
                            POI.create().init(
                                val, _self, 
                                _POIRendererMgr, _systemMgr
                            )
                        );
                    });

                    //Mark rendererMgr
                    curFloor.mark = _POIRendererMgr.getMark();
                });

                //Finalize rendererMgr
                _POIRendererMgr.finalize();
            }

            function _destroyIndoorPOIs() {
                //Only destroy when POIs has init'ed
                if(!_POIs) return;

                //Destroy POIs
                _POIs.forEach(function(e){
                    e.destroy();
                })
                e = null;

                //Destroy render batch
                _POIRendererMgr.destroy();
                _POIRendererMgr = null;
            }




            return _self;
        }
    };
}
);